package main

import (
	"fmt"
	"go_study/tree"
)

// 扩展类型
type myTreeNode struct {
	node *tree.Node
}

// 扩展: 实现后续遍历
func (myNode *myTreeNode) postOrder() {
	if nil == myNode || nil == myNode.node {
		return
	}

	left := myTreeNode{myNode.node.Left}
	right := myTreeNode{myNode.node.Right}
	left.postOrder()
	right.postOrder()
	myNode.node.Print()
}

/**
将main函数入口和方法分开, 测试包结构封装效果
*/
func main() {
	var root tree.Node
	fmt.Println(root)

	root = tree.Node{Value: 3}
	root.Value = 4
	root.Right = &tree.Node{}
	root.Left = &tree.Node{5, nil, nil}
	root.Right.Left = new(tree.Node)
	root.Left.Right = tree.CreateTreeNode(2)
	fmt.Println(root, root.Right, root.Left)

	// nodes slice
	nodes := []tree.Node{
		{Value: 3},
		{},
		{Value: 3, Right: &root},
	}
	fmt.Println(nodes)

	fmt.Println("--- Creating struct method ---")
	root.Print()
	tree.Print(root)

	fmt.Println("--- Testing update value ---")
	root.Right.SetValue(3)
	root.Right.Print() // 还是0, 没被改变, 所以证明了"值传递"

	// 可以看到调用的setValue和setValueReal作为值接收者和指针接收者, 他们的形参不同, 而实参不用改变, 这是go编译器帮我们做的人性化处理
	root.Right.SetValueReal(3)
	root.Right.Print() // 3， 指针传递, 值会改变

	pRoot := &root
	pRoot.SetValueReal(100)
	pRoot.Print()

	// Testing nil node invoke method
	var bRoot *tree.Node
	bRoot.SetValueReal(200)

	fmt.Println("--- Node Traverse ---")
	root.Traverse()

	fmt.Println("--- 后序遍历 ---")
	//myTreeNode{&root}.postOrder() // 这样会报错:  cannot call pointer method on myTreeNode literal
	myRoot := myTreeNode{&root}
	myRoot.postOrder()
}
